package com.jerome.fs.sync;

import com.jerome.fs.util.ThreadPoolFactory;

import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Service Center
 *
 * @author Jerome
 * @date 2023/9/12
 */
public class CenterServer {
    private Socket socket;
    private ExecutorService pool;
    /**
     *  Close if no heartbeat within 15 seconds
     */
    private long keepAlineTime = 15 * 1000;
    private long lastTime = System.currentTimeMillis();
    /**
     * Implementation of the service center logic
     */
    private CenterServerHandler handler;

    public CenterServer(Socket socket,CenterServerHandler handler) {
        this.handler =handler;
        this.socket = socket;
        pool = new ThreadPoolExecutor(1, 1,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1), new ThreadPoolFactory("CenterServer"));
        //请求接收对象
        pool.submit(new ReceiveWatchDog());
    }


    /**
     * Receive response messages
     */
    private class ReceiveWatchDog implements Runnable {

        @Override
        public void run() {
            while (true) {
                try {
                    if (socket.getInputStream().available() > 0) {
                        lastTime = System.currentTimeMillis();
                        handler.handle(socket);
                    } else {
                        //15秒没有心跳结束
                        if (System.currentTimeMillis() - lastTime > keepAlineTime) {
                            socket.close();
                            break;
                        }
                        Thread.sleep(10);
                    }
                } catch (Exception e) {
                    //报错结束线程
                    e.printStackTrace();
                    try {
                        socket.close();
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    break;
                }
            }

        }
    }
}
